package com.sapuo.enroll.utils;

import lombok.extern.slf4j.Slf4j;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

/**
 * @Author: lhm
 * @Date: 2020/9/9 18:47
 * @Description:
 */
@Slf4j
@Component
public class IpUtil {

    /**
     * 判断是否是ipv4
     *
     * @param ipv4
     * @return
     */
    public static boolean isIpv4(String ipv4) {
        if (ipv4 == null || ipv4.length() == 0) {
            // 字符串为空或者空串
            return false;
        }
        String[] parts = ipv4.split("\\.");
        if (parts.length != 4) {
            // 分割开的数组根本就不是4个数字
            return false;
        }
        for (int i = 0; i < parts.length; i++) {
            try {
                int n = Integer.parseInt(parts[i]);
                if (n < 0 || n > 255) {
                    // 数字不在正确范围内
                    return false;
                }
            } catch (NumberFormatException e) {
                // 转换数字不正确
                return false;
            }
        }

        return true;
    }

    /**
     * 获取请求ip
     *
     * @param request
     * @param index
     * @return
     */
    public static String getIpByIndex(HttpServletRequest request, int index) {
        if (index < 1) {
            return "";
        }

        String ip = null;
        String unknown = "unknown";

        try {
            // X-Forwarded-For：Squid 服务代理
            String ipAddresses = request.getHeader("x-forwarded-for");
            log.info("x-forwarded-for value is [{}]", ipAddresses);

            if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
                // Proxy-Client-IP：apache 服务代理
                ipAddresses = request.getHeader("Proxy-Client-IP");
            }

            if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
                // WL-Proxy-Client-IP：weblogic 服务代理
                ipAddresses = request.getHeader("WL-Proxy-Client-IP");
            }

            if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
                // HTTP_CLIENT_IP：有些代理服务器
                ipAddresses = request.getHeader("HTTP_CLIENT_IP");
            }

            if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
                // X-Real-IP：nginx服务代理
                ipAddresses = request.getHeader("X-Real-IP");
            }

            // 有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
            // it开发平台取第二个为用户真实ip
            if (ipAddresses != null && ipAddresses.length() != 0) {
                ip = ipAddresses.split(",")[index - 1].trim();
            }

            // 还是不能获取到，最后再通过request.getRemoteAddr();获取
            if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            log.error("IPUtil get ip error by index [{}]", index, e);
        }

        return ip;
    }

    /**
     * 获取x-forwarded-for信息
     * 
     * @param request
     * @return
     */
    public static String getXForwardedForInfo(HttpServletRequest request) {
        return request.getHeader("x-forwarded-for");
    }

    /**
     * 获取cmnet出口ip
     *
     * @param request
     * @param index
     * @return
     */
    public static String getCmNetIp(HttpServletRequest request, int index) {
        String ip = null;
        try {
            // X-Forwarded-For：Squid 服务代理
            String ipAddresses = request.getHeader("x-forwarded-for");
            log.info("x-forwarded-for value is [{}]", ipAddresses);

            // it开发平台取第一个,且将%到最后截取掉
            if (ipAddresses != null && ipAddresses.length() != 0) {
                ip = ipAddresses.split(",")[0].trim();
                if (ip.contains("%")){
                    ip = ip.substring(0, ip.indexOf("%"));
                }
            }
        } catch (Exception e) {
            log.error("IPUtil get ip error by index [{}]", index, e);
        }

        return ip;
    }
    
    /***
     * 
     * @param request
     * @return ipAddress; 可能是 IPV4 或  IPV6的地址
     */
    public static String getIpAdrress(HttpServletRequest request) {
        String ip = null;
        String unknown = "unknown";

        //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        log.info("X-Forwarded-For:{}",ipAddresses);
        Enumeration<String> headerNames = request.getHeaderNames();

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
//            ip = ipAddresses.split(",")[0];
        	ip = getRealIp(ipAddresses);
        }

        //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    private static final String ipv6Local = ",FE80,FEC0,";
    private static final String ipv4local = ",10.,127,172,192,224,010,100,";
     
    private static String getRealIp(String ips) {
    	if(StringUtils.isEmpty(ips)) {
    		return "";
    	}else {
    		String ip = "" ;
        	String[] addresses = ips.split(",");
        	for(String one : addresses) {
        		if(StringUtils.isEmpty(one)) {
        			continue;
        		}
        		if(one.indexOf(":")> -1 && one.length()>4) { //ipv6
        			if(ipv6Local.indexOf(","+one.trim().toUpperCase().substring(0,4)+",") > -1 ){
        				continue;
        			}else {
        				ip = one.trim();
        				break;
        			}
        		}else {
        			if(ipv4local.indexOf(","+one.trim().substring(0,3)+",") > -1 ){
        				continue;
        			}else {
        				ip = one.trim();
        				break;
        			}
        		}
        	}
        	return ip;
    	}
    }
    


}
